/*{
"CATEGORIES": [
"Masking",
"Utility"
],
"CREDIT": "by VIDVOX / v002 / Andrew Benson",
"DESCRIPTION": "Creates a raw optical flow mask from the input image",
"INPUTS": [
{
"NAME": "inputImage",
"TYPE": "image"
},
{
"DEFAULT": 10,
"LABEL": "Scale",
"MAX": 50,
"MIN": 0,
"NAME": "inputScale",
"TYPE": "float"
},
{
"DEFAULT": 0.01,
"LABEL": "Offset",
"MAX": 0.5,
"MIN": 0,
"NAME": "inputOffset",
"TYPE": "float"
},
{
"DEFAULT": 0.2,
"LABEL": "Noise Removal",
"MAX": 1,
"MIN": 0,
"NAME": "inputLambda",
"TYPE": "float"
},
{
"DEFAULT": 1,
"MAX": 1,
"MIN": 0,
"NAME": "maskOpacity",
"TYPE": "float"
}
],
"ISFVSN": "2",
"PASSES": [
{
"TARGET": "maskBuffer"
},
{
"PERSISTENT": true,
"TARGET": "delayBuffer"
},
{
}
]
}
*/
// based on v002 Optical Flow which is itself a port of Andrew Bensons HS Flow implementation on the GPU.
// https://github.com/v002/v002-Optical-Flow
const vec4 coeffs = vec4(0.2126, 0.7152, 0.0722, 1.0);
float gray(vec4 n)
{
return (n.r + n.g + n.b)/3.0;
}
void main()
{
// on the first pass generate the mask using the previous delayBuffer and inputImage
// on the 2nd pass update the delayBuffer to hold inputImage
// on the 3rd pass output the new mask
if (PASSINDEX == 0) {
// convert to grayscale
vec4 a = IMG_THIS_PIXEL(inputImage) * coeffs;
float brightness = gray(a);
a = vec4(brightness);
vec4 b = IMG_THIS_PIXEL(delayBuffer) * coeffs;
brightness = gray(b);
b = vec4(brightness);
vec2 x1 = vec2(inputOffset * RENDERSIZE.x, 0.0);
vec2 y1 = vec2(0.0,inputOffset * RENDERSIZE.y / 2.0);
vec2 texcoord0 = isf_FragNormCoord.xy * RENDERSIZE;
vec2 texcoord1 = isf_FragNormCoord.xy * RENDERSIZE;
//get the difference
vec4 curdif = b-a;
//calculate the gradient
vec4 gradx = IMG_PIXEL(delayBuffer, texcoord1+x1)-IMG_PIXEL(delayBuffer, texcoord1-x1);
gradx += IMG_PIXEL(inputImage, texcoord0+x1)-IMG_PIXEL(inputImage, texcoord0-x1);
vec4 grady = IMG_PIXEL(delayBuffer, texcoord1+y1)-IMG_PIXEL(delayBuffer, texcoord1-y1);
grady += IMG_PIXEL(inputImage, texcoord0+y1)-IMG_PIXEL(inputImage, texcoord0-y1);
vec4 gradmag = sqrt((gradx*gradx)+(grady*grady)+vec4(inputLambda));
vec4 vx = curdif*(gradx/gradmag);
float vxd = gray(vx);//assumes greyscale
//format output for flowrepos, out(-x,+x,-y,+y)
vec2 xout = vec2(max(vxd,0.),abs(min(vxd,0.)))*inputScale;
vec4 vy = curdif*(grady/gradmag);
float vyd = gray(vy);//assumes greyscale
//format output for flowrepos, out(-x,+x,-y,+y)
vec2 yout = vec2(max(vyd,0.),abs(min(vyd,0.)))*inputScale;
vec4 mask = clamp(vec4(xout.xy,yout.xy), 0.0, 1.0);
gl_FragColor = mask;
}
else if (PASSINDEX == 1) {
gl_FragColor = IMG_THIS_PIXEL(inputImage);
}
else {
// NOW DO SOMETHING WITH THE MASK
vec4 mask = IMG_THIS_NORM_PIXEL(maskBuffer);
//mask.a = 1.0;
mask.a = mix(mask.a, 1.0, maskOpacity);
gl_FragColor = mask;
}
}